{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "c08a2673-f489-417a-b42a-2f7182d3cc3b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "        <iframe\n",
       "            width=\"100%\"\n",
       "            height=\"650\"\n",
       "            src=\"http://127.0.0.1:8051/\"\n",
       "            frameborder=\"0\"\n",
       "            allowfullscreen\n",
       "            \n",
       "        ></iframe>\n",
       "        "
      ],
      "text/plain": [
       "<IPython.lib.display.IFrame at 0x20541b17110>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# double_slit_interference.py\n",
    "import dash\n",
    "from dash import dcc, html, Input, Output\n",
    "import plotly.graph_objects as go\n",
    "import numpy as np\n",
    "import math\n",
    "\n",
    "app = dash.Dash(__name__)\n",
    "\n",
    "app.layout = html.Div([\n",
    "    html.H1(\"双缝干涉实验 - 交互式演示\", style={'textAlign': 'center'}),\n",
    "    \n",
    "    html.Div([\n",
    "        html.Div([\n",
    "            html.Label(\"双缝间距 d (mm):\"),\n",
    "            dcc.Slider(\n",
    "                id='slit-separation-slider',\n",
    "                min=0.1,\n",
    "                max=2.0,\n",
    "                value=0.5,\n",
    "                step=0.05,\n",
    "                marks={0.1: '0.1', 0.5: '0.5', 1.0: '1.0', 1.5: '1.5', 2.0: '2.0'}\n",
    "            ),\n",
    "        ], style={'width': '25%', 'display': 'inline-block', 'padding': '15px'}),\n",
    "        \n",
    "        html.Div([\n",
    "            html.Label(\"缝屏距离 L (m):\"),\n",
    "            dcc.Slider(\n",
    "                id='screen-distance-slider',\n",
    "                min=0.5,\n",
    "                max=3.0,\n",
    "                value=1.5,\n",
    "                step=0.1,\n",
    "                marks={0.5: '0.5', 1.0: '1.0', 1.5: '1.5', 2.0: '2.0', 2.5: '2.5', 3.0: '3.0'}\n",
    "            ),\n",
    "        ], style={'width': '25%', 'display': 'inline-block', 'padding': '15px'}),\n",
    "        \n",
    "        html.Div([\n",
    "            html.Label(\"光波长 λ (nm):\"),\n",
    "            dcc.Slider(\n",
    "                id='wavelength-slider',\n",
    "                min=400,\n",
    "                max=700,\n",
    "                value=532,\n",
    "                step=10,\n",
    "                marks={400: '400', 500: '500', 600: '600', 700: '700'}\n",
    "            ),\n",
    "        ], style={'width': '25%', 'display': 'inline-block', 'padding': '15px'}),\n",
    "        \n",
    "        html.Div([\n",
    "            html.Label(\"光源单色性:\"),\n",
    "            dcc.Slider(\n",
    "                id='coherence-slider',\n",
    "                min=0.1,\n",
    "                max=1.0,\n",
    "                value=0.9,\n",
    "                step=0.1,\n",
    "                marks={0.1: '差', 0.5: '中', 0.9: '好', 1.0: '理想'}\n",
    "            ),\n",
    "        ], style={'width': '25%', 'display': 'inline-block', 'padding': '15px'})\n",
    "    ]),\n",
    "    \n",
    "    html.Div([\n",
    "        html.Div([\n",
    "            html.Label(\"环境振动:\"),\n",
    "            dcc.Slider(\n",
    "                id='vibration-slider',\n",
    "                min=0,\n",
    "                max=1.0,\n",
    "                value=0.1,\n",
    "                step=0.1,\n",
    "                marks={0: '无', 0.5: '中等', 1.0: '严重'}\n",
    "            ),\n",
    "        ], style={'width': '25%', 'display': 'inline-block', 'padding': '15px'}),\n",
    "        \n",
    "        html.Div([\n",
    "            html.Label(\"缝宽 (μm):\"),\n",
    "            dcc.Slider(\n",
    "                id='slit-width-slider',\n",
    "                min=10,\n",
    "                max=200,\n",
    "                value=50,\n",
    "                step=10,\n",
    "                marks={10: '10', 50: '50', 100: '100', 150: '150', 200: '200'}\n",
    "            ),\n",
    "        ], style={'width': '25%', 'display': 'inline-block', 'padding': '15px'})\n",
    "    ]),\n",
    "    \n",
    "    dcc.Graph(id='interference-pattern'),\n",
    "    dcc.Graph(id='intensity-profile'),\n",
    "    \n",
    "    html.Div([\n",
    "        html.Div(id='fringe-spacing-display', style={'fontSize': '18px', 'fontWeight': 'bold', 'margin': '10px'}),\n",
    "        html.Div(id='theory-explanation', style={'fontSize': '14px', 'margin': '10px', 'textAlign': 'left'})\n",
    "    ], style={'textAlign': 'center', 'margin': '20px', 'padding': '15px', 'border': '1px solid #ccc'}),\n",
    "    \n",
    "    html.Div([\n",
    "        html.H3(\"理论公式推导\"),\n",
    "        html.P(\"双缝干涉条纹间距公式: Δx = λL/d\"),\n",
    "        html.P(\"其中:\"),\n",
    "        html.Ul([\n",
    "            html.Li(\"Δx: 相邻明纹或暗纹间距\"),\n",
    "            html.Li(\"λ: 光波长\"),\n",
    "            html.Li(\"L: 缝屏距离\"), \n",
    "            html.Li(\"d: 双缝间距\")\n",
    "        ])\n",
    "    ], style={'margin': '20px', 'padding': '15px', 'border': '1px solid #ccc', 'backgroundColor': '#f9f9f9'})\n",
    "])\n",
    "\n",
    "@app.callback(\n",
    "    [Output('interference-pattern', 'figure'),\n",
    "     Output('intensity-profile', 'figure'),\n",
    "     Output('fringe-spacing-display', 'children'),\n",
    "     Output('theory-explanation', 'children')],\n",
    "    [Input('slit-separation-slider', 'value'),\n",
    "     Input('screen-distance-slider', 'value'),\n",
    "     Input('wavelength-slider', 'value'),\n",
    "     Input('coherence-slider', 'value'),\n",
    "     Input('vibration-slider', 'value'),\n",
    "     Input('slit-width-slider', 'value')]\n",
    ")\n",
    "def update_interference(d, L, wavelength, coherence, vibration, slit_width):\n",
    "    # 单位转换\n",
    "    d_mm = d  # 双缝间距，毫米\n",
    "    d_m = d * 1e-3  # 转换为米\n",
    "    L_m = L  # 缝屏距离，米\n",
    "    lambda_nm = wavelength  # 波长，纳米\n",
    "    lambda_m = wavelength * 1e-9  # 转换为米\n",
    "    a_m = slit_width * 1e-6  # 缝宽，米\n",
    "    \n",
    "    # 计算条纹间距\n",
    "    fringe_spacing = (lambda_m * L_m) / d_m  # 米\n",
    "    fringe_spacing_mm = fringe_spacing * 1000  # 毫米\n",
    "    \n",
    "    # 创建屏幕坐标\n",
    "    x = np.linspace(-50, 50, 1000)  # 屏幕位置，毫米\n",
    "    x_m = x * 1e-3  # 转换为米\n",
    "    \n",
    "    # 双缝干涉强度公式\n",
    "    # 考虑单缝衍射调制和双缝干涉\n",
    "    beta = (np.pi * a_m / (lambda_m * L_m)) * x_m\n",
    "    alpha = (np.pi * d_m / (lambda_m * L_m)) * x_m\n",
    "    \n",
    "    # 避免除以零\n",
    "    beta_safe = np.where(beta == 0, 1e-10, beta)\n",
    "    \n",
    "    # 单缝衍射包络\n",
    "    single_slit = (np.sin(beta_safe) / beta_safe) ** 2\n",
    "    \n",
    "    # 双缝干涉\n",
    "    double_slit = (np.cos(alpha)) ** 2\n",
    "    \n",
    "    # 总强度\n",
    "    intensity = single_slit * double_slit\n",
    "    \n",
    "    # 考虑光源单色性和环境振动的影响\n",
    "    coherence_factor = coherence\n",
    "    vibration_factor = 1 - vibration * 0.5\n",
    "    \n",
    "    # 添加噪声模拟实际条件\n",
    "    noise_level = (1 - coherence) * 0.1 + vibration * 0.2\n",
    "    intensity = intensity * coherence_factor * vibration_factor\n",
    "    intensity = intensity + np.random.normal(0, noise_level, len(intensity))\n",
    "    intensity = np.clip(intensity, 0, 1)\n",
    "    \n",
    "    # 创建干涉图样图像\n",
    "    pattern_fig = go.Figure()\n",
    "    \n",
    "    # 生成二维干涉图样\n",
    "    y = np.linspace(-20, 20, 200)\n",
    "    X, Y = np.meshgrid(x, y)\n",
    "    \n",
    "    # 创建二维强度分布\n",
    "    intensity_2d = np.outer(np.ones_like(y), intensity)\n",
    "    \n",
    "    pattern_fig.add_trace(go.Heatmap(\n",
    "        x=x, y=y, z=intensity_2d,\n",
    "        colorscale='Gray',\n",
    "        showscale=False\n",
    "    ))\n",
    "    \n",
    "    pattern_fig.update_layout(\n",
    "        title=\"双缝干涉条纹图样\",\n",
    "        xaxis_title=\"屏幕位置 (mm)\",\n",
    "        yaxis_title=\"\",\n",
    "        height=300,\n",
    "        margin=dict(l=50, r=50, t=50, b=50)\n",
    "    )\n",
    "    \n",
    "    # 创建光强分布曲线\n",
    "    profile_fig = go.Figure()\n",
    "    \n",
    "    profile_fig.add_trace(go.Scatter(\n",
    "        x=x, y=intensity,\n",
    "        mode='lines',\n",
    "        line=dict(color='blue', width=2),\n",
    "        name='光强分布'\n",
    "    ))\n",
    "    \n",
    "    # 标记明纹位置\n",
    "    max_positions = []\n",
    "    for i in range(1, len(intensity)-1):\n",
    "        if intensity[i] > intensity[i-1] and intensity[i] > intensity[i+1] and intensity[i] > 0.3:\n",
    "            max_positions.append(x[i])\n",
    "    \n",
    "    # 标记前几个明纹\n",
    "    for i, pos in enumerate(max_positions[:5]):\n",
    "        profile_fig.add_trace(go.Scatter(\n",
    "            x=[pos], y=[intensity[np.argmin(np.abs(x-pos))]],\n",
    "            mode='markers+text',\n",
    "            marker=dict(size=10, color='red'),\n",
    "            text=[f'明纹{i+1}'],\n",
    "            textposition='top center',\n",
    "            showlegend=False\n",
    "        ))\n",
    "    \n",
    "    profile_fig.update_layout(\n",
    "        title=\"光强分布曲线\",\n",
    "        xaxis_title=\"屏幕位置 (mm)\",\n",
    "        yaxis_title=\"相对光强\",\n",
    "        height=300,\n",
    "        margin=dict(l=50, r=50, t=50, b=50)\n",
    "    )\n",
    "    \n",
    "    # 理论解释\n",
    "    theory_text = [\n",
    "        f\"条纹间距理论值: {fringe_spacing_mm:.3f} mm\",\n",
    "        html.Br(),\n",
    "        f\"影响因素分析:\",\n",
    "        html.Br(),\n",
    "        f\"- 光源相干性: {'良好' if coherence > 0.8 else '一般' if coherence > 0.5 else '较差'}\",\n",
    "        html.Br(), \n",
    "        f\"- 环境振动: {'轻微' if vibration < 0.3 else '中等' if vibration < 0.7 else '严重'}\",\n",
    "        html.Br(),\n",
    "        f\"- 实际应用: 半导体光刻技术利用类似原理实现纳米级图案化\"\n",
    "    ]\n",
    "    \n",
    "    return pattern_fig, profile_fig, f\"条纹间距: {fringe_spacing_mm:.3f} mm\", theory_text\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    app.run(debug=False, host='127.0.0.1', port=8051)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b5d3e918-7a10-4480-bba0-ef8c159703ea",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.1"
  },
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "state": {},
    "version_major": 2,
    "version_minor": 0
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
